package com.ssl.spring.security.auth.fileter;

import com.ssl.spring.security.util.TokeUtil;
import com.ssl.spring.security.auth.entity.SecurityUserDetail;
import com.ssl.spring.security.constant.SecurityConstant;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 描述：token 过滤器：验证token有效性
 *
 * @author ssl
 * @create 2021/5/27 0027.
 */
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    /**
     * Same contract as for {@code doFilter}, but guaranteed to be
     * just invoked once per request within a single request thread.
     * See {@link #shouldNotFilterAsyncDispatch()} for details.
     * <p>Provides HttpServletRequest and HttpServletResponse arguments instead of the
     * default ServletRequest and ServletResponse ones.
     *
     * @param request
     * @param response
     * @param filterChain
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        String authToken = request.getHeader(SecurityConstant.REQUEST_HEADER_TOKEN);

        if (StringUtils.isBlank(authToken) || null != SecurityContextHolder.getContext().getAuthentication()) {
            // 未携带 authToken  不做任何处理
            filterChain.doFilter(request, response);
            return;
        }

        // 携带了 authToken ，则根据token中信息获取userDetail信息

        SecurityUserDetail securityUserDetail = TokeUtil.getUserDetail(authToken);

        UsernamePasswordAuthenticationToken authenticationToken =
                new UsernamePasswordAuthenticationToken(securityUserDetail.getAuthUser().getUsername(),
                        authToken,securityUserDetail.getAuthorities());

        SecurityContextHolder.getContext().setAuthentication(authenticationToken);

        filterChain.doFilter(request, response);
    }
}
